#ifndef PROCESSCONTRONL_H
#define PROCESSCONTRONL_H

#include <QThread>
#include <QDebug>
#include <QObject>

class ProcessContronl;
class ProcessContronlImpl : public QObject
{
    Q_OBJECT
public:
    ProcessContronlImpl()
    {
        m_thread.setObjectName("processContronlImpl");
        moveToThread(&m_thread);
        m_thread.start();
    }
    ~ProcessContronlImpl()
    {}

    void proess(ProcessContronl* control)
    {
        QMetaObject::invokeMethod(this,[=](){
            qDebug() << "in ProcessContronlImpl::pross " << QThread::currentThread() << ": hello world!";
            emit success(control);
        });
    }
    /*  1.say() 方法是直接调用的，没有使用 QMetaObject::invokeMethod() 或任何线程间通信机制.
    *   2.即使 ProcessContronlImpl 对象移动到了新线程，直接调用方法仍然会在调用者线程(这里是主线程)执行
    */
    void say()
    {
        qDebug() << "in ProcessContronlImpl::say " << QThread::currentThread() << ": say hi!";
    }
signals:
    void success(ProcessContronl* control);
private:
    QThread m_thread;
};


class ProcessContronl : public QObject
{
    Q_OBJECT
public:
    ProcessContronl():m_impl(std::make_shared<ProcessContronlImpl>())
    {
        connect(m_impl.get(), &ProcessContronlImpl::success, this, [=](){
            qDebug() << "success received in thread:" << QThread::currentThread();
            emit success();
        });
    }
    void press()
    {
        m_impl->proess(this);
    }
    void say()
    {
        m_impl->say();
    }
signals:
    void success();
private:
    std::shared_ptr<ProcessContronlImpl> m_impl;
};


#endif // PROCESSCONTRONL_H
